//引入依赖
import Router from 'koa-router';
import Redis from 'koa-redis';
import nodeMailer from 'nodemailer';

//引入模型
import User from '../dbs/models/users';

//引入配置
//来源于 http://www.passportjs.org/docs/
/**
 * Passport 是Node.js 的身份验证中间件。Passport 非常灵活和模块化，可以不显眼地插入任何 基于Express的 Web 应用程序。一套全面策略支持认证使用的用户名和密码
 */
// 用户名和密码验证库
import Passport from './utils/passport';
//邮箱配置
import EmailConfig from '../dbs/config';
//封装的请求
import axios from './utils/axios';


let router = new Router({
  //让文件路由都有前缀
  prefix: '/users'
});

//获取redis客户端
let Store = new Redis().client;

//注册接口
router.post('/signup', async (ctx) => {
  const {
    username,
    password,
    email,
    code
  } = ctx.request.body;

  //比对用法发送邮箱验证码
  if (code) {
    /**
     * 关于redis官网里写的Hashes数据结构
     * HMSET user:1000 username antirez password P1pp0 age 34
     * 以上可以看作成一个对象
     */

    //hget()方法找到key底下的field的值
    //redis > HSET myhash field1 "foo"
    //redis > HGET myhash field1 => "foo"

    //拿到保存到redis数据库里的验证码
    //去数据库里拿对应的field
    //hget(key, field)方法
    const savedCode = await Store.hget(`nodemail:${username}`, 'code');
    const savedExpireTime = await Store.hget(`nodemail:${username}`, 'expire');

    //比较用户提交的验证码与redis数据库保存的验证码是否一致
    if (code === savedCode) {
      //比较现在的时间判断是否过期
      if (new Date().getTime() - savedExpireTime > 0) {
        //过期了
        ctx.body = {
          code: -1,
          msg: '验证码已过期，请重新尝试'
        }
        return false;
      }
    } else {
      ctx.body = {
        code: -1,
        msg: '请填写正确的验证码'
      }
    }
  } else {
    ctx.body = {
      code: -1,
      msg: '请填写验证码'
    }
  }

  let user = await User.find({
    username
  })

  if (user.length) {
    ctx.body = {
      code: -1,
      msg: '用户已存在'
    }
    return false;
  }

  //添加用户
  let addNewUser = await User.create({
    username,
    password,
    email
  })

  if (addNewUser) {
    //添加用户成功并登入
    let res = await axios.post('/users/signin', {
      username,
      password
    });

    if (res.data && res.data.code === 0) {
      ctx.body = {
        code: 0,
        msg: '注册成功!',
        user: res.data.user
      }
    } else {
      ctx.body = {
        code: -1,
        msg: 'error!'
      }
    }
  } else {
    ctx.body = {
      code: -1,
      msg: '注册失败!'
    }
  }

});

//登录接口
router.post('/signin', async (ctx, next) => {
  //本地策略校验密码
  return Passport.authenticate('local', function (err, user, info, status) {
    if (err) {
      ctx.body = {
        code: -1,
        msg: err
      }
    } else {
      //登录成功
      if (user) {
        ctx.body = {
          code: 0,
          msg: '登录成功',
          user
        }
        return ctx.login(user);
      } else {
        ctx.body = {
          code: 1,
          //info包含具体的异常信息
          msg: info,
        }
      }
    }
  })(ctx, next);
});

//点击发送验证码时请求的接口 
//检验邮件验证码是否正确的接口
router.post('/verify', async (ctx, next) => {
  let username = ctx.request.body.username;
  const saveExpire = await Store.hget(`nodemail:${username}`, 'expire');

  //频繁刷接口时
  if (saveExpire && new Date().getTime() - saveExpire < 0) {
    ctx.body = {
      code: -1,
      msg: '验证请求过于频繁,1分钟内只能验证一次'
    }
    return false;
  }

  //配置传输方式
  let transporter = nodeMailer.createTransport({
    host: EmailConfig.smtp.host,
    //默认587
    port: 587,
    secure: false,
    auth: {
      user: EmailConfig.smtp.user,
      pass: EmailConfig.smtp.pass,
    },
  });

  //设置接收信息
  let recvInfo = {
    code: EmailConfig.smtp.code(),
    expire: EmailConfig.smtp.expire(),
    //验证码接收方
    email: ctx.request.body.email,
    user: ctx.request.body.username
  }

  //配置邮箱
  let mailOptions = {
    //发件人
    from: `"认证邮件"<${EmailConfig.smtp.user}>`,
    //收件人
    to: recvInfo.email,
    //主题
    subject: '《美团网》注册码',
    //邮件文本内容
    html: `您在美团网申请的注册码是${recvInfo.code}`
  }

  //执行发送邮件
  await transporter.sendMail(mailOptions, (err, info) => {
    if (err) {
      return console.log('error');
    } else {
      //hset => m: multiple 设置多个
      Store.hmset(
        `nodemail:${recvInfo.user}`,
        'code',
        recvInfo.code,
        'expire',
        recvInfo.expire,
        'email',
        recvInfo.email
      );
    }
  });

  ctx.body = {
    code: 0,
    msg: '验证码已经发送，有限时间为1分钟'
  }

});

//退出接口
router.get('/exit', async (ctx, next) => {
  await ctx.logout();

  //检验是否有登录
  //退出成功
  if (!ctx.isAuthenticated()) {
    ctx.body = {
      code: 0
    }
  } else {
    //退出失败
    ctx.body = {
      code: -1
    }
  }
});

//获取用户接口
router.get('/getUser', async (ctx, next) => {
  if (ctx.isAuthenticated()) {
    const {
      username,
      email
    } = ctx.session.passport.user;

    ctx.body = {
      user: username,
      email
    }
  } else {
    ctx.body = {
      user: '',
      email: ''
    }
  }
});

export default router;
